<template>
  <div class="progress-container">
    <div class="file-info">
      <span class="file-name">{{ downloadFile.name }}</span>
      <span class="file-size">{{ formatSize(downloadFile.size) }}</span>
      <span class="download-status" :class="statusClass">{{ statusText }}</span>
    </div>

    <!-- 下载进度 -->
    <div class="progress-item">
      <el-progress 
        :text-inside="true"
        :stroke-width="16"
        :percentage="downloadFile.downloadPercentage"
        :status="statusColor"
      />
    </div>
    
    <!-- 大文件下载的分片信息 -->
    <div v-if="isLargeFile && !isCompleted" class="chunk-info">
      <span>分片: {{ downloadFile.chunksDownloaded }}/{{ downloadFile.totalChunks }}</span>
    </div>
    
    <div class="download-controls">
      <span>{{ downloadFile.downloadSpeed }}</span>
      
      <!-- 下载控制按钮 -->
      <template v-if="!isCompleted">
        <el-button 
          v-if="isActiveDownload"
          circle link 
          @click="togglePause"
        >
          <el-icon size="20">
            <VideoPause v-if="!downloadFile.isPaused" />
            <VideoPlay v-else />
          </el-icon>
        </el-button>
      </template>
      
      <!-- 重新下载按钮 -->
      <el-button 
        v-if="isCompleted"
        circle link 
        @click="restartDownload"
        title="重新下载"
      >
        <el-icon size="20">
          <Refresh />
        </el-icon>
      </el-button>
      
      <!-- 删除按钮 -->
      <el-button 
        circle link 
        @click="removeDownload"
        title="删除任务"
      >
        <el-icon size="20">
          <Close />
        </el-icon>
      </el-button>
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted } from 'vue'
import { VideoPause, VideoPlay, Close, Refresh } from "@element-plus/icons-vue"
import axios from 'axios';
import { useDownloadStore } from '@/stores/downloadStore';

const props = defineProps({
  downloadFile: {
    type: Object,
    required: true
  }
})

const downloadStore = useDownloadStore();

// 常量定义
const CHUNK_SIZE = 533536; // 1MB分片大小
const MAX_RETRIES = 3; // 最大重试次数

// 计算属性
const isPaused = computed(() => props.downloadFile.isPaused);
const isDownloading = computed(() => 
  props.downloadFile.status === 'downloading' && 
  props.downloadFile.downloadPercentage < 100
);
const isActiveDownload = computed(() => isDownloading.value);
const isLargeFile = computed(() => props.downloadFile.size > 10 * 1024 * 1024);
const isCompleted = computed(() => props.downloadFile.status === 'completed');
const downloadProgress = computed(() => props.downloadFile.downloadPercentage);
const statusColor = computed(() => {
  if (isPaused.value) return 'warning';
  if (props.downloadFile.downloadPercentage === 100) return 'success';
  if (props.downloadFile.status === 'error') return 'exception';
  return null;
});

const statusText = computed(() => {
  switch(props.downloadFile.status) {
    case 'downloading': return '下载中';
    case 'paused': return '已暂停';
    case 'completed': return '已完成';
    case 'error': return '下载失败';
    default: return '等待中';
  }
});

const statusClass = computed(() => {
  return {
    'status-downloading': props.downloadFile.status === 'downloading',
    'status-paused': props.downloadFile.status === 'paused',
    'status-completed': props.downloadFile.status === 'completed',
    'status-error': props.downloadFile.status === 'error'
  };
});

// 格式化文件大小
const formatSize = (bytes) => {
  if (!bytes) return '0 B';
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
  return (bytes / 1048576).toFixed(1) + ' MB';
};

// 控制下载暂停/继续
const togglePause = () => {
  if (isPaused.value) {
    downloadStore.resumeDownload(props.downloadFile.id);
    startDownload();
  } else {
    downloadStore.pauseDownload(props.downloadFile.id);
  }
};

// 移除下载任务
const removeDownload = () => {
  downloadStore.removeDownload(props.downloadFile.id);
};

// 重新开始下载
const restartDownload = () => {
  // 重置任务状态
  downloadStore.addDownload({
    id: props.downloadFile.id,
    name: props.downloadFile.name,
    fileType: props.downloadFile.fileType,
    size: props.downloadFile.size
  });
  
  // 开始下载
  startDownload();
};

// 计算下载速度
const calculateSpeed = (startTime, loadedBytes) => {
  const elapsed = (Date.now() - startTime) / 1000; // 秒
  if (elapsed < 0.1) return '0 KB/s'; // 避免除以0
  const speed = loadedBytes / elapsed; // 字节/秒
  if (speed < 1024) return speed.toFixed(0) + ' B/s';
  if (speed < 1048576) return (speed / 1024).toFixed(1) + ' KB/s';
  return (speed / 1048576).toFixed(1) + ' MB/s';
};



// 下载小文件（修改）
const downloadSmallFile = async (fileId, fileName, fileSize) => {
  try {
    const startTime = Date.now();
    let actualFileName = fileName; // 存储实际文件名
    let mimeType = 'application/octet-stream'; // 默认MIME类型
    
    const response = await axios({
      method: 'get',
      url: `http://localhost:8083/download/file/${fileId}`,
      responseType: 'blob',
      onDownloadProgress: (progressEvent) => {
        if (progressEvent.lengthComputable) {
          const percent = Math.round((progressEvent.loaded / progressEvent.total) * 100);
          const speed = calculateSpeed(startTime, progressEvent.loaded);
          downloadStore.updateProgress(fileId, percent, speed);
        }
      }
    });
    
    // 从响应头获取实际文件名和内容类型
    const contentDisposition = response.headers['content-disposition'];
    if (contentDisposition) {
      const fileNameMatch = contentDisposition.match(/filename="?(.+)"?/);
      if (fileNameMatch && fileNameMatch[1]) {
        actualFileName = fileNameMatch[1];
      }
    }
    
    if (response.headers['content-type']) {
      mimeType = response.headers['content-type'];
    }
    
    // 创建带正确类型的Blob
    const blob = new Blob([response.data], { type: mimeType });
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', actualFileName); // 使用服务器返回的文件名
    document.body.appendChild(link);
    link.click();
    
    // 清理
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
  } catch (error) {
    throw new Error(`小文件下载失败: ${error.message}`);
  }
};

// 大文件下载 - 修复版（确保直接开始下载）
const downloadLargeFile = async (fileId, fileName, fileSize) => {
  try {
    console.log('开始大文件下载流程');
    
    // 1. 初始化分片下载并获取分片信息
    const chunkInfo = await initChunkDownload(fileId);
    if (!chunkInfo || !chunkInfo.totalChunks) {
      console.log(chunkInfo);
      throw new Error('无法获取文件分片信息');
    }
    
    const chunkCount = chunkInfo.totalChunks;
    const chunkSizes = chunkInfo.encryptedChunkSizes;
    
    console.log(`获取分片信息成功: 总分片数=${chunkCount}`);
    
    // 2. 更新总片数到状态管理
    downloadStore.updateChunkInfo(fileId, -1, chunkCount);
    
    // 3. 下载所有分片
    console.log('开始下载分片数据');
    const chunks = Array(chunkCount).fill(null);
    const startTime = Date.now();
    let totalDownloaded = 0;
    
    // 4. 下载所有分片 (从1到总分片数)
    for (let i = 1; i <= chunkCount; i++) {
      // 检查是否暂停
      const currentDownload = downloadStore.getDownload(fileId);
      if (!currentDownload || currentDownload.isPaused) {
        console.log('下载已暂停');
        return;
      }
      
      let retryCount = 0;
      let chunkData = null;
      
      while (retryCount <= MAX_RETRIES) {
        try {
          console.log(`下载分片: ${i}/${chunkCount}`);
          // 下载分片
          chunkData = await downloadChunk(fileId, i);
          
          // 存储分片数据 (索引从0开始)
          chunks[i - 1] = chunkData;
          
          // 更新已下载字节数（使用实际分片大小）
          const chunkKey = i.toString(); // 转换为字符串键
          const actualChunkSize = chunkSizes[chunkKey] || chunkData.byteLength;
          totalDownloaded += actualChunkSize;
          
          // 计算进度和速度（确保不超过100%）
          const percent = Math.min(99, Math.floor((totalDownloaded / fileSize) * 100));
          const speed = calculateSpeed(startTime, totalDownloaded);
          
          // 更新状态
          downloadStore.updateProgress(fileId, percent, speed);
          downloadStore.updateChunkInfo(fileId, i, chunkCount);
          
          console.log(`分片 ${i} 下载完成, 进度: ${percent}%`);
          break; // 成功则跳出重试循环
        } catch (chunkError) {
          retryCount++;
          console.error(`分片 ${i} 下载失败 (尝试 ${retryCount}/${MAX_RETRIES}):`, chunkError);
          
          if (retryCount > MAX_RETRIES) {
            throw new Error(`分片 ${i} 下载失败: ${chunkError.message}`);
          }
          // 指数退避重试
          await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
        }
      }
    }
    
    console.log('所有分片下载完成，开始合并文件');
    
    // 5. 合并分片
    const fullBlob = new Blob(chunks.filter(chunk => chunk !== null));
    
    // 6. 创建下载链接
    const url = window.URL.createObjectURL(fullBlob);
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', fileName);
    document.body.appendChild(link);
    link.click();
    
    // 7. 清理
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
    
    // 8. 标记下载完成
    downloadStore.completeDownload(fileId);
    console.log('文件下载完成');
    
  } catch (error) {
    console.error('大文件下载失败:', error);
    downloadStore.setError(fileId);
  }
};

// 初始化分片下载 - 简化版
const initChunkDownload = async (fileId) => {
  try {
    console.log(`初始化分片下载: ${fileId}`);
    const response = await axios.get(`http://localhost:8083/download/chunk/init/${fileId}`);
    
    if (response.data && response.data.data) {
      const fileInfo = response.data.verificationReport;
      
      console.log('初始化成功:', fileInfo);
      
      // 返回分片信息对象
      return {
        totalChunks: fileInfo.totalChunks || 0,
        encryptedChunkSizes: fileInfo.encryptedChunkSizes || {}
      };
    }
    return null;
  } catch (error) {
    console.error('分片信息获取失败:', error);
    return null;
  }
};

// 下载单个分片 - 优化版
const downloadChunk = async (fileId, chunkIndex) => {
  try {
    console.log(`下载分片: ${fileId} - ${chunkIndex}`);
    const response = await axios({
      method: 'get',
      url: `http://localhost:8083/download/chunk/${fileId}`,
      params: { index: chunkIndex },
      responseType: 'arraybuffer',
      timeout: 30000 // 30秒超时
    });
    
    console.log(`分片 ${chunkIndex} 下载成功`);
    return response.data;
  } catch (error) {
    console.error(`分片 ${chunkIndex} 下载失败:`, error);
    throw error;
  }
};

// 开始下载 - 修改为直接调用下载流程
const startDownload = async () => {
  try {
    const fileId = props.downloadFile.id;
    const fileName = props.downloadFile.name;
    const fileSize = props.downloadFile.size;
    
    console.log(`开始下载: ${fileName} (${fileId})`);
    
    // 更新状态为下载中
    downloadStore.resumeDownload(fileId);
    
    // 根据文件大小选择下载方式
    if (fileSize < 10 * 1024 * 1024) {
      console.log('使用小文件下载方式');
      await downloadSmallFile(fileId, fileName, fileSize);
    } else {
      console.log('使用大文件下载方式');
      await downloadLargeFile(fileId, fileName, fileSize);
    }
    
    // 下载完成
    downloadStore.completeDownload(fileId);
    console.log('下载完成');
    
  } catch (error) {
    console.error('[ERROR] 下载失败:', error);
    downloadStore.setError(props.downloadFile.id);
  }
};

// 组件挂载时开始下载（如果状态是下载中且未暂停）
onMounted(() => {
  console.log('组件挂载，检查是否需要开始下载');
  if (props.downloadFile.status === 'downloading' && !props.downloadFile.isPaused) {
    console.log('自动开始下载');
    startDownload();
  }
});
</script>


<style scoped>
.progress-container {
  padding: 15px;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  margin-bottom: 15px;
  background: #f8fafc;
  position: relative;
  transition: all 0.3s;
}

.file-info {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
  font-size: 14px;
  align-items: center;
}

.file-name {
  font-weight: bold;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 40%;
}

.file-size {
  margin-left: 10px;
  color: #606266;
  white-space: nowrap;
  font-size: 13px;
}

.download-status {
  margin-left: 10px;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}

.status-downloading {
  background-color: #ecf5ff;
  color: #409eff;
}

.status-paused {
  background-color: #fdf6ec;
  color: #e6a23c;
}

.status-completed {
  background-color: #f0f9eb;
  color: #67c23a;
}

.status-error {
  background-color: #fef0f0;
  color: #f56c6c;
}

.progress-item {
  display: flex;
  align-items: center;
  margin: 8px 0;
}

.chunk-info {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.download-controls {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin-top: 8px;
  gap: 8px;
}
</style>